package net.asfun.jvalog.http;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.logging.Level;

import javax.servlet.ServletConfig;
import javax.servlet.http.*;

import net.asfun.jvalog.except.CacheException;
import net.asfun.jvalog.except.DataException;
import net.asfun.jvalog.except.InteractException;
import net.asfun.jvalog.except.ViewException;
import net.asfun.jvalog.misc.Caster;
import net.asfun.jvalog.misc.ThreadHelper;
import net.asfun.jvalog.misc.Setting;
import net.asfun.jvalog.service.DualCacher;
import static net.asfun.jvalog.misc.Log.logger;

public class JvalogServlet extends HttpServlet {
	
	private static final long serialVersionUID = 200904120912L;
	
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		String uri = req.getRequestURI();
		logger.finest(uri);
		String result = null;
		String arr[] = uri.split("/");
		
		try {
			ThreadHelper.startup();
		
			if ( arr.length < 2 ) {
				result = DualCacher.main(0);
			}
			else if ( "post".equals(arr[1]) ) {
				int page = 0;
				if ( arr.length > 2 ) {
					page = Caster.toInt(getSlogan(arr[2]));
				}
				result = DualCacher.main(page);
			}
			else if ( "page".equals(arr[1]) ) {
				if ( arr.length > 2 ) {
					result = DualCacher.page(getSlogan(arr[2]));
				} else {
					result = DualCacher.main(0);
				}
			}
			else if ( "rss".equals(arr[1])) {
				result = DualCacher.rss();
			}
			else if ( "sitemap".equals(arr[1]) ) {
				result = DualCacher.sitemap();
			}
			else if ( "atom".equals(arr[1]) || "feed".equals(arr[1]) ) {
				result = DualCacher.atom();
			}
			else if ( "tag".equals(arr[1]) ) {
				if ( arr.length > 2 ) {
					String slogan = getSlogan(arr[2]);
					int page = 0;
					if ( arr.length > 3 ) {
						page = Caster.toInt(getSlogan(arr[3]));
					}
					result = DualCacher.tag(slogan, page);
				} else {
					result = DualCacher.tag();
				}
			}
			else if ( "category".equals(arr[1]) ) {
				if ( arr.length > 2 ) {
					String slogan = getSlogan(arr[2]);
					int page = 0;
					if ( arr.length > 3 ) {
						page = Caster.toInt(getSlogan(arr[3]));
					}
					result = DualCacher.category(slogan, page);
				} else {
					//TODO
//					result = DualCacher.category();
					result = DualCacher.notFound();
				}
			}
			else if ( "media".equals(arr[1]) ) {
				if ( arr.length > 2) 
					result = DualCacher.media(URLDecoder.decode(arr[2], "utf-8"));
				else 
					result = DualCacher.notFound();
			}
			//like /2009/04/16/post-title.html
			else if ( arr[1].matches("\\d{4}") ) {
				int page = Caster.toInt(req.getParameter("p"));
				if ( arr.length == 2) {
					result = DualCacher.date(new String[]{arr[1]}, page);
				} else if ( arr.length == 3) {
					if ( arr[2].matches("\\d{2}") ) {
						result = DualCacher.date(new String[]{arr[1], arr[2]}, page);
					} else {
						result = DualCacher.notFound();
					}
				} else if ( arr.length == 4) {
					if ( arr[3].matches("\\d{2}") ) {
						result = DualCacher.date(new String[]{arr[1], arr[2], arr[3]}, page);
					} else {
						result = DualCacher.notFound();
					}
				} else {
					if ( arr[2].matches("\\d{2}") && arr[3].matches("\\d{2}") ) {
						result = DualCacher.post(getSlogan(arr[4]), arr[3], arr[2], arr[1]);
					} else {
						result = DualCacher.notFound();
					}
				}
			}
			else {
				result = DualCacher.main(0);
			}
		} catch (DataException de) {
			logger.log(Level.SEVERE, de.getMessage(), de);
			result = DualCacher.error();
		} catch (InteractException ie) {
			logger.info(ie.getMessage() + ": " + uri);
			result = DualCacher.notFound();
		} catch (CacheException ce)	{ 
			logger.log(Level.SEVERE, ce.getMessage(), ce);
			result = Setting.errorPage;
		} catch (ViewException ve) {
			logger.log(Level.SEVERE, ve.getMessage(), ve);
			result = Setting.errorPage;
		} catch (Exception e) {
			logger.log(Level.SEVERE, e.getMessage(), e);
			result = Setting.errorPage;
		}
		
		ThreadHelper.header().setHeaders(resp);
		ThreadHelper.shutdown();
		
		resp.getWriter().print(result);

	}
	
	private String getSlogan(String str) throws UnsupportedEncodingException {
		//TODO use dot in slogan
		return URLDecoder.decode(str.split("\\.")[0], "utf-8");
	}
	
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
		throws IOException {
		resp.sendError(403);
	}
	
	public void init(ServletConfig config) {
		Setting.root = config.getServletContext().getRealPath("/");
	}
}
